/*
 * Cliente.h

 *
 *  Entidad principal de la aplicación Cliente
 */

#ifndef CLIENTE_H_
#define CLIENTE_H_

#include "Comunicador.h"
#include "ColaBloqueante.h"
#include "CommandMaker.h"
#include "FilePoller.h"
#include "MyException.h"
#include "FileSyncHandler.h"
#include "Thread.h"
#include "NotificationListener.h"

#include "ClientCommandInterpreter.h"

// DELTA ENCODING
#include "DeltaHandler.h"

#include <queue>
#include <unistd.h>

class Cliente : public Thread {
	Comunicador comunicador;	// Objeto que usa socket para comunicarse
	std::fstream indiceHashes;	// Posee el indice actualizado
	FilePoller	poller;			// Entidad que se encarga del polling al repo local
	unsigned int intervaloPolling;
	FileSyncHandler syncHandler;	// Sincroniza el repo local
	NotificationListener notifListener;

	std::string nombreUsuario, password, syncPath;	// Datos del cliente

	ColaBloqueante<std::string> colaNotif;

	public:
		Cliente(const char* username, const char* pass, const char* syncPath,
				const char* indexPath, unsigned int intervaloTiempoPolling);
		virtual ~Cliente();

		void iniciarTrabajo(int numPuerto, const char* ip) throw();

		//	Mensajes al Server
		// Obtiene la lista de archivos y hashes para corroborar updates
		void getRepoServer();

		FileSyncHandler& getSyncHandler();
		Comunicador& getComunicador() {return (this->comunicador);};

		/* Arma la lista de diferencias de archivos nuevos y borrados del server
		 * cuando el user esta desconectado, usando las listas que
		 * arma el FilePoller
		 */
		std::list<Diferencia*> getListaDiferenciasIniciales();

		void run();

		// Cierra conexiones
		void terminarTrabajo();

		/* 	Este metodo se encarga de iterar la lista de diferencias y enviar y
		*	recibir los
		*	mensajes correspondientes en cada caso
		*/
		void manejarDiferencias(std::list<Diferencia*> diferencias);

		// Se encarga de parsear y ejecutar las actualizaciones
		void manejarActualizaciones(std::stringstream& stream);

		// Metodo que encapsula el login al server
		void loginToServer();

		void manejarNotificaciones();
};

#endif
